﻿
using Common.Logging;
using F23.StringSimilarity;
using HuChaHuRen.HeNan.XiangCheng.Common;
using HuChaHuRen.HeNan.XiangCheng.Models;
using HuChaHuRen.HeNan.XiangCheng.Models.Messages;
using HuChaHuRen.HeNan.XiangCheng.Models.Others;
using Newtonsoft.Json;
using PACS.Client.Model;
using Quartz;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace HuChaHuRen.HeNan.XiangCheng.Upload
{
    public class PACSUploadJob : IJob
    {
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger("PACSUploadJob");
        private BaseConfig baseCfg = ConfigHelp.GetBaseConfig();
        private List<CheckItemComp> checkItemComps = null;
        readonly string excelFullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", "comp.xlsx");
        public void Execute(IJobExecutionContext context)
        {
            PublishStatus("运行中...");

            Publish("进入 [PACSUploadJob] 方法.");

            var dbContext = DataProvider.GetNewConn();
            if (dbContext == null)
            {
                PublishError("数据库连接失败,请检查连接字符串.");
                return;
            }
            else
            {
                dbContext.Ado.CommandTimeOut = 5000;
            }

            int searchRange = baseCfg.UploadRecordDateRange;
            if (searchRange <= 0)
            {
                searchRange = 3;
            }

            ReadItemCodeInfo();

            DateTime searchStartTime = DateTime.Now.AddDays(-searchRange);

            List<OrgConfig> orgList = baseCfg.OrgConfigs;
            if (orgList == null || orgList.Count == 0)
            {
                PublishError($"未配置机构信息,任务终止.");
                PublishStatus("就绪");
                return;
            }

            List<string> orgIds = orgList.Select(it => it.OrgID).ToList();
            List<OrganizationInfo> orgRecordList = null;
            try
            {
                orgRecordList = dbContext.Queryable<OrganizationInfo>()
                       .In(it => it.Id, orgIds)
                       .ToList();
            }
            catch (Exception ex)
            {
                PublishError($"查询'OrganizationInfo'失败,请检查数据库连接.\n{ex.Message}");
                PublishError($"{nameof(PACSUploadJob)}Job已终止");
                PublishStatus("就绪");
                return;
            }

            Publish($"待上传机构'{orgRecordList.Count}'家.");

            foreach (var org in orgRecordList)
            {
                string hospCode = orgList.FirstOrDefault(it => it.OrgID == org.Id).HospitalCode;

                Publish($"当前上传机构:'{org.OrgName}'.");

                //List<ModelA> prepareUploadRecords = null;
                List<int> sIdList = new List<int>();
                try
                {
                    sIdList = dbContext.Queryable<Patient, Study, Report, HCHR_XiangCheng_UploadRecord>((pat, stu, rep, uploadRecord) => new object[] {
                        JoinType.Left,pat.Id == stu.PatientID,
                        JoinType.Left,stu.Id == rep.StudyID,
                        JoinType.Left,stu.Id == uploadRecord.StudyID,})
                        .Where((pat, stu, rep, uploadRecord) => pat.OrgID == org.Id)
                        .Where((pat, stu, rep, uploadRecord) => stu.CreateTime > searchStartTime)
                        .Where((pat, stu, rep, uploadRecord) => (uploadRecord.StudyUploadSucceed == true && uploadRecord.ReportUploadSucceed == false && uploadRecord.ErrorMessage == null))
                        .Where((pat, stu, rep, uploadRecord) => !SqlFunc.IsNullOrEmpty(rep.Approver) || !SqlFunc.IsNullOrEmpty(rep.ReportDocName))
                        .Select((pat, stu, rep, uploadRecord) => stu.Id)
                        .ToList();
                }
                catch (Exception ex)
                {
                    PublishError($"{nameof(PACSUploadJob)}查询检查异常:\n{ex.Message}");
                    PublishStatus("就绪");
                    return;
                }

                Publish($"查询到待上传的报告记录'{sIdList.Count}'条({searchRange}天内).");

                if (!sIdList.Any())
                {
                    Publish($"未查询到可上传的检查记录。当前机构上传中止.");
                }
                else
                {
                    if (baseCfg.ReocrdUploadDatePriority)
                    {
                        sIdList.Sort();
                    }

                    if (baseCfg.TestMode)
                    {

                        if (baseCfg.MaxUploadLimit > 0)
                        {
                            Publish($"当前为测试模式,上传记录限制为设定值'{baseCfg.MaxUploadLimit}'条.");
                            sIdList = sIdList.Take(baseCfg.MaxUploadLimit).ToList();
                        }
                        else
                        {
                            Publish($"当前为测试模式,上传记录限制为默认值'{baseCfg.MaxUploadLimit}'条.");
                            sIdList = sIdList.Take(200).ToList();
                        }
                    }

                    List<Patient> pats = null;
                    List<Study> stus = null;
                    List<Report> reps = null;
                    dynamic uploadRecords = null;

                    try
                    {
                        pats = dbContext.Queryable<Patient, Study>((pat, stu) => new object[]
                                       {
                            JoinType.Left,pat.Id == stu.PatientID
                                       })
                                       .In((pat, stu) => stu.Id, sIdList)
                                       .Select((pat, stu) => pat)
                                       .ToList();
                        stus = dbContext.Queryable<Study>()
                            .In(it => it.Id, sIdList)
                            .ToList();
                        reps = dbContext.Queryable<Report>()
                           .In(it => it.StudyID, sIdList)
                           .ToList();
                        uploadRecords = dbContext.Queryable<HCHR_XiangCheng_UploadRecord>()
                            .Where(it => it.CreateTime > searchStartTime && it.ErrorMessage == null)
                            .Select(it => new { ID = it.ID, SID = it.StudyID, StudyPK = it.StudyPK, StudyUpScss = it.StudyUploadSucceed, RepUploadScss = it.ReportUploadSucceed })
                            .ToList();
                    }
                    catch (Exception ex)
                    {
                        Publish($"查询出现异常:\n{ex.Message}");
                    }

                    Publish($"开始循环上传...");


                    foreach (var id in sIdList)
                    {
                        var stu = stus.FirstOrDefault(it => it.Id == id);
                        var pat = pats.FirstOrDefault(it => it.Id == stu.PatientID);
                        var rep = reps.FirstOrDefault(it => it.StudyID == id);

                        string inf = $"正在上传'{stu.PatientName}'的'{stu.ShootPart}'检查.";
                        CheckInfo stuInfo = new CheckInfo();
                        //Predicate<dynamic> pred = (dynamic) =>
                        //{
                        //    return (int)dynamic.SID == id;
                        //};

                        try
                        {
                            var matchedUploadRecord = (uploadRecords as IEnumerable<dynamic>).FirstOrDefault((it) => it.SID == id);
                            HCHR_XiangCheng_UploadRecord currentRecord = new HCHR_XiangCheng_UploadRecord();
                            currentRecord.CreateTime = DateTime.Now;
                            if (matchedUploadRecord != null)
                            {
                                currentRecord.ID = matchedUploadRecord.ID;
                                currentRecord.StudyID = matchedUploadRecord.SID;
                                logger.Info($"currentRecord.ID={currentRecord.ID}");
                            }

                            if (string.IsNullOrEmpty(pat.IDCard))
                            {
                                AddErrorRecord(dbContext, stu.Id, $"身份证号为空.");
                                continue;
                            }

                            if (matchedUploadRecord == null || matchedUploadRecord.StudyUpScss == false)
                            {

                                #region CheckInfo Build
                                stuInfo.ProviderID = baseCfg.PlatformConfig.ProviderID;
                                string timesmp = DateTime.Now.ToString("yyyyMMddHHmmss");
                                stuInfo.Timestamp = timesmp;
                                stuInfo.ProviderKey = Hash.CalculateMD5($"{baseCfg.PlatformConfig.Password}{timesmp}"); ;
                                stuInfo.HospitalCode = hospCode;
                                string formatSID = stu.Id.ToString("D6");
                                stuInfo.StudyPk = $"{hospCode}_{formatSID}";
                                stuInfo.PlatformIndex = "";
                                stuInfo.PatientName = pat.ChineseName;
                                stuInfo.PatientSpellName = PinYinTool.GetPinyinFull(stuInfo.PatientName);

                                switch (pat.Sex)
                                {
                                    case 0:
                                        stuInfo.Sex = "M";
                                        break;
                                    case 1:
                                        stuInfo.Sex = "F";
                                        break;
                                    default:
                                        stuInfo.Sex = "O";
                                        break;
                                }
                                stuInfo.PatientCareer = pat.ZhiYe;
                                stuInfo.PatientNation = pat.Nation;
                                if (pat.Birthday != null &&
                                    pat.Birthday.Value != null &&
                                    pat.Birthday.Value.Year > 1900)
                                {
                                    stuInfo.Birthday = pat.Birthday.Value.ToString("yyyy-MM-dd");
                                }
                                else
                                {
                                    stuInfo.Birthday = null;
                                }
                                stuInfo.PhoneNumber = pat.Tel;
                                stuInfo.Address = pat.Address;
                                stuInfo.Age = stu.Age;

                                if (stu.AgeUnit != null)
                                {
                                    if (stu.AgeUnit.Contains("岁"))
                                    {
                                        stuInfo.AgeUnit = "year";
                                    }
                                    else if (stu.AgeUnit.Contains("月"))
                                    {
                                        stuInfo.AgeUnit = "month";

                                    }
                                    else if (stu.AgeUnit.Contains("天"))
                                    {
                                        stuInfo.AgeUnit = "day";
                                    } 
                                }
                                else
                                {
                                    stuInfo.AgeUnit = "year";
                                }
                                //ckInfo.AgeUnit = stu.AgeUnit;
                                switch (stu.PatientType)
                                {
                                    case 1:
                                        stuInfo.HisPatientType = "0";
                                        stuInfo.AdmissionId = stu.ClinicNumber;
                                        stuInfo.AdmissionLocation = stu.BedID;
                                        break;
                                    case 2:
                                        stuInfo.HisPatientType = "1";
                                        stuInfo.AdmissionId = stu.InPatientNumber;
                                        break;
                                    case 3:
                                        stuInfo.HisPatientType = "3";
                                        break;
                                    case 4:
                                        stuInfo.HisPatientType = "2";
                                        break;
                                    default:
                                        stuInfo.HisPatientType = "9";
                                        break;
                                }

                                stuInfo.RequestDoctor = stu.DoctorName;
                                stuInfo.RequestDepartment = stu.UnitName;
                                string stdItemCode = "";

                                stdItemCode = MatchComp(stu.CheckType, stu.CheckItem, stu.ShootPart);
                                if (!string.IsNullOrEmpty(stdItemCode))
                                {
                                    stuInfo.StandardItemCode = stdItemCode; 
                                }
                                else
                                {
                                    stuInfo.StandardItemCode = "";
                                }
                                stuInfo.ItemName = stu.ShootPart;
                                stuInfo.SaveMoney = 0f;
                                stuInfo.RequestZone = "";
                                stuInfo.Modality = stu.CheckType;
                                stuInfo.AccessionNumber = stu.DsNumber;
                                stuInfo.PatientId = pat.PatientUID;
                                stuInfo.StudyInstanceUid = stu.StudyUID;
                                stuInfo.MultiStudyInstanceUid = null;
                                stuInfo.StudyTime = stu.CreateTime.Value.ToString("yyyyMMddHHmmss");
                                stuInfo.MediId = null;
                                stuInfo.HisRequestId = pat.WBM;
                                stuInfo.IdCardType = "00";
                                stuInfo.IdCardNo = pat.IDCard;
                                stuInfo.CinicalDiagnosis = stu.ClinicalDiagnosis;
                                stuInfo.PatientHistory = stu.ClinicalHistory;
                                stuInfo.HealthCardNo = null;
                                stuInfo.AppendPositions = new List<CheckPosition>
                                {
                                    new CheckPosition
                                    {
                                    studyPosition = stu.CheckItem,
                                    checkItem = stu.ShootPart
                                    }
                                };



                                stuInfo.ApplicantPhone = null;
                                stuInfo.ExamAttention = "0";
                                stuInfo.DeviceCode = null;
                                stuInfo.Privacy = "0";
                                stuInfo.Complain = null;
                                stuInfo.InsuranceCardNo = null;
                                stuInfo.ImageCount = "0";
                                stuInfo.Height = null;
                                stuInfo.Weight = null;
                                stuInfo.NeedQrCode = "1";
                                //ckInfo.ReportStatus = "60";
                                //ckInfo.ReportDoctor = rep.ReportDocName;
                                #endregion

                                string postContent = JsonConvert.SerializeObject(stuInfo);
                                string betterPostC = JsonUtil.BetterJson(postContent);
                                logger.Info($"StudyUploadRequest:\n{betterPostC}");
                                string stuUploadUrl = baseCfg.PlatformConfig.Host + baseCfg.PlatformConfig.StudyUploadUrl;
                                string respContent = HttpOp.Post(stuUploadUrl, postContent);


                                if (string.IsNullOrEmpty(respContent))
                                {
                                    PublishError($"检查上传接口,返回为空,跳过上传(Name:'{pat.ChineseName}').");

                                    currentRecord.CreateTime = DateTime.Now;
                                    currentRecord.ErrorMessage = "studyUpload接口调用失败!";
                                    currentRecord.StudyUploadSucceed = false;
                                    currentRecord.StudyID = stu.Id;
                                    if (currentRecord.ID == 0)
                                    {
                                        var recordId = AddUploadRecord(currentRecord, dbContext);
                                        currentRecord.ID = recordId;
                                    }
                                    else
                                    {

                                        UpdateUploadRecord(currentRecord, dbContext);
                                    }
                                }
                                else
                                {
                                    //继续上传报告
                                    StudyUploadResponse resp = JsonConvert.DeserializeObject<StudyUploadResponse>(respContent);
                                    if (resp == null)
                                    {
                                        string fmContent = JsonUtil.BetterJson(respContent);
                                        PublishError($"StudyUpload返回报文序列化失败:\n{fmContent}");
                                    }
                                    else
                                    {
                                        if (!"000000".Equals(resp.resultCode))
                                        {
                                            string fmContent = JsonUtil.BetterJson(respContent);
                                            PublishError($"StudyUpload返回报文:\n{fmContent}");
                                            AddErrorRecord(dbContext, stu.Id, resp.resultDesc);
                                            //PublishError($"StudyUpload接口执行错误(Name:'{pat.ChineseName}'),\n{resp.resultDesc}");
                                        }
                                        else
                                        {
                                            logger.Info($"Succeed Record Manipu");
                                            currentRecord.CreateTime = DateTime.Now;
                                            currentRecord.ErrorMessage = null;
                                            currentRecord.StudyUploadSucceed = true;
                                            currentRecord.CheckSerialNum = resp.resultData.checkSerialNum;
                                            currentRecord.QRCode = resp.resultData.qrCode;
                                            currentRecord.StudyPK = resp.resultData.studyPk;
                                            currentRecord.StudyID = stu.Id;
                                            if (currentRecord.ID == null || currentRecord.ID == 0)
                                            {
                                                var recordId = AddUploadRecord(currentRecord, dbContext);
                                                currentRecord.ID = recordId;
                                            }
                                            else
                                            {

                                                UpdateUploadRecord(currentRecord, dbContext);
                                            }

                                            Publish($"'{pat.ChineseName}'的检查信息已上传.");


                                        }
                                    }
                                }
                            }



                            //继续下一步 RepUpload
                            #region Report Build

                            ReportInfo rInfo = new ReportInfo();
                            rInfo.ProviderID = baseCfg.PlatformConfig.ProviderID;
                            rInfo.Timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");

                            rInfo.ProviderKey = Hash.CalculateMD5($"{baseCfg.PlatformConfig.Password}{rInfo.Timestamp}");
                            string fmStuID = stu.Id.ToString("D6");
                            rInfo.StudyPk = $"{hospCode}_{fmStuID}";

                            rInfo.ReportId = $"{hospCode}_{rep.Id}";
                            rInfo.HospitalCode = hospCode;
                            rInfo.ReportStatus = "70";
                            rInfo.ReportDoctor = rep.ReportDocName;
                            rInfo.ReportDoctorCode = null;
                            rInfo.ReportDoctorDigital = null;
                            rInfo.ReportTime = rep.CreateTime.Value.ToString("yyyyMMddHHmmss");
                            rInfo.ReportDiagnose = rep.DgnOpnTxt;
                            rInfo.ReportDescribe = rep.ImgRptTxt;
                            rInfo.ReportAdvice = string.Empty;
                            rInfo.ApproveDoctor = rep.Approver;
                            rInfo.ApproveDoctorCode = null;
                            rInfo.ApproveDoctorDigital = null;

                            if (rep.ApprovalTime == null || (rep.ApprovalTime.Value != null && rep.ApprovalTime.Value.Year < 2000))
                            {
                                rInfo.ApproveTime = rep.CreateTime.Value.AddSeconds(213).ToString("yyyyMMddHHmmss");
                            }
                            else
                            {
                                rInfo.ApproveTime = rep.ApprovalTime.Value.ToString("yyyyMMddHHmmss");
                            }
                            //rInfo.ApproveTime = rep.ApprovalTime.Value.ToString("yyyyMMddHHmmss");
                            rInfo.SliceThickness = null;
                            rInfo.IsurgencyReport = "0";
                            rInfo.MasculineFlag = rep.IsAbnormal.ToString();
                            rInfo.InfectiousFlag = "0";
                            rInfo.CrisisFlag = "0";
                            #endregion

                            string payload = JsonConvert.SerializeObject(rInfo);
                            string fmPayload = JsonUtil.BetterJson(payload);
                            logger.Info($"ReportUploadRequest:\n{fmPayload}");
                            string reportUplaodResp = HttpOp.Post(baseCfg.PlatformConfig.ReportUploadUrl, payload);
                            if (string.IsNullOrEmpty(reportUplaodResp))
                            {
                                PublishError($"报告上传接口,返回为空,跳过上传(Name:'{pat.ChineseName}'),原报文为:\n{fmPayload}.");
                                currentRecord.ErrorMessage = "ReportUpload接口调用失败!";
                                currentRecord.StudyUploadSucceed = true;
                                currentRecord.ReportUploadSucceed = false;

                                UpdateUploadRecord(currentRecord, dbContext);
                            }
                            else
                            {

                                //继续上传报告
                                Response repResp = JsonConvert.DeserializeObject<Response>(reportUplaodResp);
                                if (repResp == null)
                                {
                                    string fmContent = JsonUtil.BetterJson(reportUplaodResp);
                                    PublishError($"ReportUpload返回报文序列化失败:\n{fmContent}");
                                }
                                else
                                {
                                    if (!"000000".Equals(repResp.resultCode))
                                    {
                                        string fmContent = JsonUtil.BetterJson(reportUplaodResp);
                                        Publish($"ReportUpload返回报文:\n{fmContent}");

                                        //PublishError($"StudyUpload接口执行错误,{repResp.resultDesc}");
                                        currentRecord.ErrorMessage = "reportUpload接口调用失败!";
                                        currentRecord.StudyUploadSucceed = true;
                                        currentRecord.ReportUploadSucceed = false;
                                        currentRecord.CreateTime = DateTime.Now;

                                        UpdateUploadRecord(currentRecord, dbContext);

                                    }
                                    else
                                    {
                                        currentRecord.ErrorMessage = null;
                                        currentRecord.StudyUploadSucceed = true;
                                        currentRecord.ReportUploadSucceed = true;
                                        currentRecord.CreateTime = DateTime.Now;
                                        UpdateUploadRecord(currentRecord, dbContext);

                                        Publish($"'{pat.ChineseName}'的报告信息上传成功.");
                                    }
                                }
                            }

                        }
                        catch (Exception ex)
                        {
                            Publish($"上传发生异常:\n{ex.Message}");

                            AddErrorRecord(dbContext, id, ex.Message);
                        }
                    }

                }

                Publish($"机构'{org.OrgName}'的本次上传任务结束.");

                if (checkItemComps != null && checkItemComps.Any())
                {
                    WriteItemCodeInfo(checkItemComps);
                    Publish("更新对照表。");
                }
            }

            Publish("本次 [PACSUploadJob] 上传任务结束.");
            PublishStatus("就绪");
        }


        private void AddErrorRecord(SqlSugarClient dbContext, int sid, string err)
        {
            HCHR_XiangCheng_UploadRecord record = new HCHR_XiangCheng_UploadRecord();

            record.CreateTime = DateTime.Now;
            record.ErrorMessage = err;
            record.StudyUploadSucceed = false;
            record.ReportUploadSucceed = false;
            record.CheckSerialNum = null;
            record.QRCode = null;
            record.StudyPK = null;
            record.StudyID = sid;
            var recordId = AddUploadRecord(record, dbContext);
        }

        private int AddUploadRecord(HCHR_XiangCheng_UploadRecord record,
            SqlSugarClient dbContext)
        {
            record.CreateTime = DateTime.Now;
            try
            {
                var id = dbContext.Insertable<HCHR_XiangCheng_UploadRecord>(record).ExecuteReturnIdentity();
                if (id > 0)
                {
                    return id;
                }
                else
                {
                    string recordContent = JsonConvert.SerializeObject(record);
                    recordContent = JsonUtil.BetterJson(recordContent);
                    logger.Error($"[AddUploadRecord]新增记录失败,Record内容为:\n{recordContent}");
                    return 0;
                }
            }
            catch (Exception ex)
            {
                string recordContent = JsonConvert.SerializeObject(record);
                recordContent = JsonUtil.BetterJson(recordContent);
                logger.Error($"Add UploadRecord error: {ex.Message}\n{recordContent}");
            }
            return 0;
        }

        private void UpdateUploadRecord(HCHR_XiangCheng_UploadRecord record,
            SqlSugarClient dbContext)
        {
            if (record.StudyID == 0)
            {
                PublishError($"[UpdateUploadRecord]record无STUID,更新失败.");
            }
            else
            {
                try
                {
                    int count = dbContext.Updateable<HCHR_XiangCheng_UploadRecord>(record)
                                .Where(it => it.StudyID == record.StudyID)
                                .ExecuteCommand();

                    if (count <= 0)
                    {
                        string recordContent = JsonConvert.SerializeObject(record);
                        recordContent = JsonUtil.BetterJson(recordContent);
                        logger.Error($"[UpdateUploadRecord]更新记录失败,Record内容为:\n{recordContent}");
                    }
                }
                catch (Exception ex)
                {
                    string json = JsonConvert.SerializeObject(record);
                    logger.Error($"update UploadRecord error\n{ex.Message}\n{json}");
                }
            }
        }

        private int ReadItemCodeInfo()
        {
            if (File.Exists(excelFullPath))
            {
                checkItemComps = ExcelOp.ReadCheckItemComp(excelFullPath);
                if (checkItemComps != null)
                {
                    logger.Info($"读取检查对照记录{checkItemComps.Count}条。");
                    return checkItemComps.Count; 
                }
                else
                {
                    logger.Info($"读取检查对照记录为null");

                }
            }
            else
            {
                logger.Info($"读取检查对照记录,文件不存在:'{excelFullPath}'");
                return 0;
            }
            return 0;

        }

        private void WriteItemCodeInfo(List<CheckItemComp> listComp)
        {
            if (File.Exists(excelFullPath))
            {
                ExcelOp.UpdateComp(listComp, excelFullPath);
            }
        }

        private string MatchComp(string checkType, string checkPart, string checkItem)
        {
            logger.Info($"dbg-01:'{checkType}'-'{checkPart}'-'{checkItem}'");
            if (checkItemComps != null && checkItemComps.Any())
            {
                List<CheckItemComp> queryScope = null;
                List<string> checkTypeList = new List<string>();
                if (checkType != "DR" && checkType != "DX")
                {
                    queryScope = checkItemComps.Where(it => it.CheckType == checkType).ToList();
                    checkTypeList.Add(checkType);
                }
                else
                {
                    queryScope = checkItemComps.Where(it => it.CheckType == "DX" || it.CheckType == "DR").ToList();
                    checkTypeList.Add("DX");
                    checkTypeList.Add("DR");
                }
                //直接匹配(历史匹配成功后)
                var specificItem = queryScope.FirstOrDefault(it => checkTypeList.Contains(it.CheckType) && it.RISCheckItem == checkItem);
                if (specificItem != null)
                {
                    logger.Info($"dbg-02-直接命中");
                    var matchOne = checkItemComps.FirstOrDefault(it => checkTypeList.Contains(it.CheckType) && it.RISCheckItem == checkItem);
                    if (matchOne != null)
                    {
                        matchOne.RISCheckPart = checkPart;
                        matchOne.RISCheckItem = checkItem;
                        return specificItem.CheckItemCode; 
                    }
                }



                double HighestScore = 0f;
                CheckItemComp mostMatchItem = null;
                foreach (var item in queryScope)
                {
                    //完全匹配
                    if (item.CheckItem.Equals(checkItem))
                    {
                        logger.Info($"dbg-完全匹配");
                        var matchOne = checkItemComps.FirstOrDefault(it => it.Index == item.Index);
                        matchOne.RISCheckPart = checkPart;
                        matchOne.RISCheckItem = checkItem;
                        logger.Info($"FullMatch CheckItem:'{item.CheckItem}'");
                        return item.CheckItemCode;
                    }
                    else
                    {
                        double score = MatchScore(item.CheckItem, checkItem);
                        if (score >= matchThresholdVal)
                        {
                            if (score > HighestScore)
                            {
                                HighestScore = score;
                            }
                            mostMatchItem = item;
                        }
                    }
                }

                //近似匹配
                if (mostMatchItem != null)
                {
                    logger.Info($"dbg-近似匹配");

                    var matchOne = checkItemComps.FirstOrDefault(it => it.Index == mostMatchItem.Index);
                    matchOne.RISCheckPart = checkPart;
                    matchOne.RISCheckItem = checkItem;
                    logger.Info($"NearestMatch CheckItem:'{checkItem} -> {mostMatchItem.CheckItem}'");

                    return mostMatchItem.CheckItemCode;
                }
                else
                {
                    logger.Info($"No Match CheckItem:{checkItem}");
                    return "";
                }
            }
            else
            {
                logger.Info($"No Match CheckItem:{checkItem}");
                return string.Empty;
            }
        }

        private void Publish(string msg)
        {
            logger.Info(msg);
            MessageHub.DefaultMessageHub.SendMessage<string>(msg);
        }

        private void PublishError(string msg)
        {
            logger.Error(msg);
            MessageHub.DefaultMessageHub.SendMessage<string>(msg);
        }

        private void PublishStatus(string status)
        {
            MessageHub.DefaultMessageHub.SendMessage<JobActivityMessage>(new JobActivityMessage
            {
                JobType = 0,
                Status = status
            });
        }


        public static double matchThresholdVal = 0.80d;
        private NormalizedLevenshtein nl;

        private double MatchScore(string val1, string val2)
        {
            if (nl == null)
            {
                nl = new NormalizedLevenshtein();
            }
            double matchScore = nl.Similarity(val1, val2);
            return matchScore;
        }
    }

    class ModelA
    {
        public Patient Pat { get; set; }

        public Study Stu { get; set; }

        public Report Rep { get; set; }
    }

    //class ModelB
    //{
    //    public string CheckType { get; set; }

    //    public string CheckPart { get; set; }

    //    public string CheckItem { get; set; }

    //    public string CHeckItemCode { get; set; }

    //}
}
